package com.example.ephuizi.stl.util;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import android.util.Log;

/**
 * Created by ephuizi@gmail.com on 2015/7/18.
 */
public class STLFile {

    private static String TAG = STLFile.class.getSimpleName();

    private int facetNum;// 三角片数量

    private FloatBuffer vertexBuffer;// 顶点 length=[faces * 3 * 3]
    private FloatBuffer normalBuffer;// 三角面片法向量的3个分量值数据length=[faces * 3 * 3]

    private float[] max;
    private float[] min;

    public STLFile(int facetNum, float[] max, float[] min, float[] vertices, float[] normals) {
        this.facetNum = facetNum;

        this.max = max;
        this.min = min;

        this.vertexBuffer = toFloatBuffer(vertices);
        this.normalBuffer = toFloatBuffer(normals);

    }

    public STLFile(int facetNum, float[] max, float[] min, FloatBuffer vertexBuffer, FloatBuffer normalBuffer) {
        this.facetNum = facetNum;

        this.max = max;
        this.min = min;

        this.vertexBuffer = vertexBuffer;
        this.normalBuffer = normalBuffer;
    }

    private static FloatBuffer toFloatBuffer(float[] a) {
        long t_begin = System.currentTimeMillis();
        FloatBuffer floatBuffer = null;
        ByteBuffer mbb = null;
        try {
            // 先初始化buffer,数组的长度*4,因为一个float占4个字节
            mbb = ByteBuffer.allocateDirect(a.length * 4);

            // 数组排列用nativeOrder
            mbb.order(ByteOrder.nativeOrder());
            floatBuffer = mbb.asFloatBuffer();
            floatBuffer.put(a);
            floatBuffer.position(0);

            STLUtil.logUseTime(TAG, "toFloatBuffer", t_begin);

        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        } finally {
            if (floatBuffer != null) {
                floatBuffer.clear();
            }
            if (mbb != null) {
                mbb.clear();
            }
        }

        return floatBuffer;
    }

    public FloatBuffer getVertexBuffer() {
        return vertexBuffer;
    }

    public int getFacetNum() {
        return facetNum;
    }

    public FloatBuffer getNormalBuffer() {
        return normalBuffer;
    }

    // 3d中点
    public float centerX() {
        return (max[0] + min[0]) / 2;
    }

    public float centerY() {
        return (max[1] + min[1]) / 2;
    }

    public float centerZ() {
        return (max[2] + min[2]) / 2;
    }

    public float distance() {
        double d = Math.sqrt(Math.pow(Math.abs(max[0]) + Math.abs(min[0]), 2) + Math.pow(Math.abs(max[0]) + Math.abs(min[0]), 2)
                + Math.pow(Math.abs(max[0]) + Math.abs(min[0]), 2));
        return (float) d;
    }

    /**
     * 在x,y,z上离原点最远的距离
     *
     * @return
     */
    public float absMax() {
        float dx = max[0] - min[0];
        float dy = max[1] - min[1];
        float dz = max[2] - min[2];
        float m = dx;
        if (m < dy)
            m = dy;
        if (m < dz)
            m = dz;
        Log.e(TAG, "dx " + dx + "dy " + dy + "dz " + dz + " m" + m);
        return m;
    }

    public float getMaxX() {
        return max[0];
    }

    public float getMaxY() {
        return max[1];
    }

    public float getMaxZ() {
        return max[2];
    }

    public float getMinX() {
        return min[0];
    }

    public float getMinY() {
        return min[1];
    }

    public float getMinZ() {
        return min[2];
    }

    public boolean isMinPointExist() {
        boolean flag = false;
        float[] tri = new float[3];
        vertexBuffer.position(0);
        for (int i = 0; i < facetNum; i++) {
            vertexBuffer.get(tri);
            if (tri[0] == min[0]) {
                if (tri[1] == min[1]) {
                    if (tri[2] == min[2]) {
                        flag = true;
                        break;
                    }
                }
            }
        }
        vertexBuffer.position(0);
        Log.e(TAG, "isMinPointExist() " + flag);
        return flag;
    }
}